package com.kgc.kmall.managerservice.service.impl;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.kgc.kmall.bean.*;
import com.kgc.kmall.managerservice.mapper.PmsSkuAttrValueMapper;
import com.kgc.kmall.managerservice.mapper.PmsSkuImageMapper;
import com.kgc.kmall.managerservice.mapper.PmsSkuInfoMapper;
import com.kgc.kmall.managerservice.mapper.PmsSkuSaleAttrValueMapper;
import com.kgc.kmall.service.SkuService;

import com.kgc.kmall.util.RedisUtil;
import com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ;
import net.minidev.json.JSONUtil;
import org.apache.dubbo.config.annotation.Service;
import org.redisson.api.RedissonClient;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;

import javax.annotation.Resource;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.UUID;

@Service
public class SkuServiceImpl implements SkuService {
    @Resource
    PmsSkuInfoMapper skuInfoMapper;
    @Resource
    PmsSkuAttrValueMapper pmsSkuAttrValueMapper;
    @Resource
    PmsSkuImageMapper pmsSkuImageMapper;
    @Resource
    PmsSkuSaleAttrValueMapper pmsSkuSaleAttrValueMapper;
    @Resource
    RedisUtil redisUtil;
    @Resource
    RedissonClient redissonClient;

    @Override
    public int saveSkuInfo(PmsSkuInfo skuInfo) {
        int i=0;
        if (skuInfo.getId()==null){
            i = skuInfoMapper.insert(skuInfo);
        }else{

        }
        //添加sku属性值
        List<PmsSkuAttrValue> skuAttrValueList = skuInfo.getSkuAttrValueList();
        if (skuAttrValueList.size() > 0) {
            pmsSkuAttrValueMapper.insertBatch( skuInfo.getId(),skuAttrValueList);
        }
        //添加平台属性值
        List<PmsSkuSaleAttrValue> skuSaleAttrValueList = skuInfo.getSkuSaleAttrValueList();
        if (skuSaleAttrValueList.size()>0){
            pmsSkuSaleAttrValueMapper.insertBatch(skuInfo.getId(),skuSaleAttrValueList);
        }
        //添加图片
        List<PmsSkuImage> skuImageList = skuInfo.getSkuImageList();
        if (skuImageList.size()>0){
            pmsSkuImageMapper.insertBatch(skuInfo.getId(),skuImageList);
        }

        return i;
    }

    @Override
    public PmsSkuInfo selectBySkuId(Long skuId) {
        PmsSkuInfo pmsSkuInfo=null;
        Jedis jedis = redisUtil.getJedis();
        String key="sku:"+skuId+":info";
        String skuInfoJson = jedis.get(key);
        if (skuInfoJson!=null){
            //解决缓存穿透
            if(skuInfoJson.equals("empty")){
                    return  null;
            }
            //从redis查数据
           pmsSkuInfo = JSON.parseObject(skuInfoJson, PmsSkuInfo.class);
           jedis.close();
        }else {
            //使用nx分布式锁，避免缓存击穿
            String skuLockKey="sku"+skuId+":lock";
            String skuLockValue= UUID.randomUUID().toString();
            String lockKey=jedis.set(skuLockKey,skuLockValue,"NX","PX",60*1000);
            if (lockKey.equals("OK")){
                //从数据库查数据
                pmsSkuInfo   = skuInfoMapper.selectByPrimaryKey(skuId);
                //解决缓存穿透,缓存雪崩
                if (pmsSkuInfo!=null){
                    //保存到redis
                    String jsonString = JSON.toJSONString(pmsSkuInfo);
                    //有效期随机，防止缓存雪崩
                    Random random=new Random();
                    int nextInt = random.nextInt(10);
                    jedis.setex(key,nextInt*60*1000,jsonString);
                }else {
                    jedis.setex(key,5*60*1000,"empty");
                }
                //删除分布式锁
             /*   String skuLockValue2 = jedis.get(skuLockKey);
                if (skuLockValue2!=null&&skuLockValue2.equals(skuLockValue)){
                    jedis.del(lockKey);
                }*/
                String script ="if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
                jedis.eval(script, Collections.singletonList(skuLockKey),Collections.singletonList(skuLockValue));
            }else {
                //如果分布式锁访问失败，线程休眠3秒，重新访问
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //抢锁失败回旋
                selectBySpuId(skuId);
            }
        }
        return pmsSkuInfo;
    }

    @Override
    public List<PmsSkuInfo> selectBySpuId(Long spuId) {
        List<PmsSkuInfo> pmsSkuInfos=null;
        Jedis jedis = redisUtil.getJedis();
        String key="spu:"+spuId+":info";
        String skuInfoJson = jedis.get(key);
        if (skuInfoJson!=null){
            //解决缓存穿透
            if(skuInfoJson.equals("empty")){
                return  null;
            }
            pmsSkuInfos =JSON.parseArray(skuInfoJson,PmsSkuInfo.class);
            jedis.close();
        }else{
            //使用nx分布式锁，避免缓存击穿
            String skuLockKey="sku"+spuId+":lock";
            String skuLockValue= UUID.randomUUID().toString();
            String lockKey=jedis.set(skuLockKey,skuLockValue,"NX","PX",60*1000);
            if (lockKey.equals("OK")){
                //从数据库查询数据
                pmsSkuInfos=skuInfoMapper.selectBySpuId(spuId);
                if (pmsSkuInfos!=null){
                    //保存到redis
                    String jsonString = JSON.toJSONString(pmsSkuInfos);
                    //有效期随机，防止缓存雪崩
                    Random random=new Random();
                    int nextInt = random.nextInt(10);
                    jedis.setex(key,nextInt*60*1000,jsonString);
                }else {
                    jedis.setex(key,5*60*1000,"empty");
                }
                //删除分布式锁
               /* String skuLockValue2 = jedis.get(skuLockKey);
                if (skuLockValue2!=null&&skuLockValue2.equals(skuLockValue)){
                    jedis.del(lockKey);
                }*/
                String script ="if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
                jedis.eval(script, Collections.singletonList(skuLockKey),Collections.singletonList(skuLockValue));
            }else {
                //如果分布式锁访问失败，线程休眠3秒，重新访问
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //抢锁失败回旋
                selectBySpuId(spuId);
            }
        }
        return pmsSkuInfos;
    }

    @Override
    public List<PmsSkuInfo> getAllSku() {
        List<PmsSkuInfo> pmsSkuInfos = skuInfoMapper.selectByExample(null);
        for (PmsSkuInfo pmsSkuInfo : pmsSkuInfos) {
            PmsSkuAttrValueExample example=new PmsSkuAttrValueExample();
            PmsSkuAttrValueExample.Criteria criteria=example.createCriteria();
            criteria.andSkuIdEqualTo(pmsSkuInfo.getId());
            List<PmsSkuAttrValue> pmsSkuAttrValues = pmsSkuAttrValueMapper.selectByExample(example);
            pmsSkuInfo.setSkuAttrValueList(pmsSkuAttrValues);
        }
        return pmsSkuInfos;
    }

    @Override
    public boolean checkPrice(Long productSkuId, BigDecimal price) {
        PmsSkuInfo pmsSkuInfo = selectBySkuId(productSkuId);
        if (price.compareTo(new BigDecimal(pmsSkuInfo.getPrice()))==0){
            return true;
        }
        return false;
    }
}
